var Flow = {
	pointToPoint: function(x1, y1, x2, y2) {
		// 计算两点之间的距离
		return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	},
	pointToLineD: function(x0, y0, x1, y1, x2, y2) {
		// 计算点到线的最短距离
		var a = this.pointToPoint(x1, y1, x2, y2);// 线段的长度
		var b = this.pointToPoint(x1, y1, x0, y0);// (x1,y1)到点的距离
		var c = this.pointToPoint(x2, y2, x0, y0);// (x2,y2)到点的距离
		if (c * c >= a * a + b * b) {
			return b; // new Point(x1, y1);
		}
		if (b * b >= a * a + c * c) {
			return c; // new Point(x2, y2);
		}
		var p = (a + b + c) / 2;// 半周长
		var s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
		return 2 * s / a;// 返回点到线的距离（利用三角形面积公式求高）
	},
	pointInPolygon: function(p, ppa) {
		// 判断点是否在多边形内 0： 区域外 1：区域内
		// p : point, ppa: polygon point array
		var cx = 0 //经过该点的水平直线与各边的交点总数
			, pc = ppa.length; // polygon point count
		var L = 10000000000; //乘L以提高精度
		p.x *= L;
		p.y *= L;
		var na = []; //将多边形的点坐标也xL
		for (var i = 0; i < pc; i++) {
			na[i] = {
				x: ppa[i].x * L,
				y: ppa[i].y * L
			}
		}
		for (var i = 0; i < pc; i++) {
			// 得到多边形的一条边
			var p1 = na[i], p2 = na[(i + 1) % pc];
			if (p1.x == p2.y) {
				// 区域内
				if (p.y == p1.y && p.x >= Math.min(p1.x, p2.x)
						&& p.x <= Math.max(p1.x, p2.x))
					return 1;
				// 区域外继续，可能有更靠外的点
				continue;
			}
			// 区域外继续，可能有更靠外的点
			if (p.y < Math.min(p1.y, p2.y) || p.y > Math.max(p1.y, p2.y))
				continue;
			// 点和线上方位
			var tx = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
			// 相交
			if (tx > p.x) {
				cx++;// 点在边上
			} else if (tx == p.x) {
				return 1;
			}
		}
		if (cx % 2 == 1) {
			return 1;
		}
		return 0;
	},
	new1: function(f, cp){
		var o = {
			t: 'subflow',
			o: f? f.id:'',
			d: {},
			m: {
				caption: f? f.name:'',
				w: cp.width(),
				h: cp.height(),
				bgColor: cp.css('background-color')
			},
			nodes: [{}] // 所有节点，0元素不使用！
		}
		this.live(o); //增加方法
		return o;
	},
	live: function(o){
		o.setCaption = function(c, w){
			o.m.caption = c;
		}
		o.addNode = function(n){
			var ns = o.nodes;
			for (var i=1; i<ns.length; i++) {
				var a = ns[i];
				if (a && (a.t == n.t) && (a.t == 'start')) {
					alert('流程图只能有一个' + Cache.base.flow.node[a.t].name + '节点');//改统一报错形式
					return -1;
				}
			}
			var i = 1; //0元素不使用！
			while (ns[i]) {
				i++;
			}
			n.id = i;
			o.nodes[i] = n;
			return i;
		}
		o.delArrow = function(a){
			function delConn(o, d, k) {
				var d = d?'n':'p', b = o[d];
				if (b.id) {
					o[d] = -1;
				} else {
					delete b[k];
				}
			}
			delConn(a.n, 0, a.id);
			delConn(a.p, 1, a.id);
			this.nodes[a.id] = null;
		}
		o.delArrows = function(a) {
			if (a && a != -1) {
				if (a.id) {
					this.delArrow(a);
				} else {
					for (var k in a) {
						this.delArrow(a[k]);
					}
				}
			}
		}
		o.delNode = function(n){
			var ns = this.nodes;
			ns[n.id] = null;
			if (n.t == 'arrow') {
				this.delArrow(n);
			} else {
				//删除与之连接的所有线条
				this.delArrows(n.p);
				this.delArrows(n.n);
			}
			delete n;
			while (!ns[ns.length - 1]) {
				ns.pop();
			}
		}
		o.draw = function(cc){
			var ns = o.nodes, m = o.m;
			cc.clearRect(0, 0, m.w, m.h);
			cc.font = '24px sans-serif';
			cc.textAlign = 'start';
			cc.textBaseline = 'top';
			cc.fillStyle = '#CCCCCC';
			cc.fillText(m.caption, 8, 8);
			for (var i=1; i < ns.length; i++) {
				if (ns[i]) {
					ns[i].draw(cc);
				}
			}
		}
		o.getNexus = function(type) {
			var c = [], ns = o.nodes;
			for (var i=1; i<ns.length; i++) {
				var z = ns[i];
				if (z && z.o && z.p) {
					for (var a in z.p) {
						a = ns[a].d;
						c.push({
							objId0: o.o,
							objType0: type,
							objCode0: o.d.code,
							objName0: o.d.name,
							objId1: z.o,
							objType1: z.t,
							objCode1: z.d.ref || z.d.code,
							objName1: z.d.name,
							way: a.way,
							async: a.async,
							memo: a.memo
						}); //引用的组件
					}
				}
			}
			return JSON.stringify(c);
		}
		o.getFaces = function() {
			var f = {}, ns = o.nodes;
			f[o.faceId] = 1;
			for (var i=1; i<ns.length; i++) {
				var z = ns[i];
				if (z && z.d && z.d.faceId) {
					f[z.d.faceId] = 1; //引用的接口
				}
			}
			var a = [];
			for (var k in f) {
				a.push(k);
			}
			return a.join(',');
		}
		o.toJson = function(replacer, space){
			var ns = o.nodes, N = Flow.BaseNode;
			var to = {
				t: o.t, // type
				o: o.o, // object reference
				m: o.m, // meta
				d: o.d, // data
				pm: o.pm, // params map
				nodes: [{}]
			}
			for (var i=1; i<ns.length; i++) {
				var z = ns[i];
				if (!z) {
					to.nodes.push(z);
					continue;
				}
				to.nodes.push(z.tinto());
			}
			return JSON.stringify(to, replacer, space);
		}
		return o;
	},
	from: function(fo, coms){
		var ns = fo.nodes, N = Flow.BaseNode;
		for (var i=1; i<ns.length; i++) {
			var a = ns[i];
			if (!a) {
				continue;
			}
			a.c = a.c || {}; //TODO
			if (a.o && coms) {
				var x = coms[a.o];
				if (x && x.d && x.m) {
					a.d = x.d;
					a.m = x.m;
				} else {
					// delete a.o;
				}
			}
			N.live(a)
			N.online(a, 'p', ns);
			N.online(a, 'n', ns);
			Flow.Nodes[a.t].live(a);
		}
		this.live(fo);
		return fo;
	}
}
Flow.BaseNode = {
	new1: function(t){
		var o = this.live({
			t: t, //type 节点类型
			d: {},
			c: {}
		});
		return o;
	},
	new2: function(z, p){
		var a = this.live({
			id: z.id, t: z.t, d: z.d, m: z.m, o: z.o, c: o.c || {}
		});
		a.x = p.x;
		a.y = p.y;
		return a;
	},
	tinto: function(z, f, a){
		var o = z[f];
		if (!o || o == -1) {
			a[f] = o;
			return;
		}
		if (o.id) {
			a[f] = o.id;
		} else {
			for (var k in o) {
				a[f].push(k);
			}
		}
	},
	online: function(z, f, ns){
		var o = z[f], a = {};
		if (o && o != -1) {
			if (o.pop) { //如果是个数组，就逐一恢复引用
				for (var j=0; j<o.length; j++) {
					var k = o[j];
					a[k] = ns[k];
				}
				z[f] = a;
			} else {
				z[f] = ns[o];
			}
		}
	},
	live: function(o){
		o.getAnchor = function(i){
			return this.getAnchors()[i];
		}
		o.byAnchor = function(p){
			var as = this.getAnchors(), s = 1000000
				, a, d, j = 0;
			for (var i=0; i<as.length; i++) {
				a = as[i];
				d = Flow.pointToPoint(a.x, a.y, p.x, p.y);
				if (d < s) {
					s = d;
					j = i;
				}
			}
			a = as[j];
			return { i: j, x: a.x, y: a.y };
		}
		o.hasNext = function(t){
			var n = this.n, b = false;
			if (!n || n.n == -1) {
				return b;
			}
			for (var k in n) {
				b = b || (n[k].d.tagCode == t);
			}
			return b;
		}
		o.count = function(t){
			var x = this[t?'n':'p'], i = 0;
			if (!x || x == -1) {
				return 0;
			}
			for (var k in x) {
				i++;
			}
			return i;
		}
		return o;
	}
}
Flow.InputNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('input');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 120, h: 40, caption: '' };
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o); //增加方法
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o); //增加方法
		return o;
	},
	live: function(o){
		o.check = function(){
			var d = o.d;
			return o.n.id && o.p && d.code && d.name && d.faceId && d.impl && d.uiCode;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h * 1.5, 120);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5, ds = o.c.status;
			cc.beginPath();
			cc.moveTo(o.x - w05, o.y + h05);
			cc.lineTo(o.x - w05 + h05, o.y - h05);
			cc.lineTo(o.x + w05, o.y - h05);
			cc.lineTo(o.x + w05 - h05, o.y + h05);
			cc.lineTo(o.x - w05, o.y + h05);
			cc.closePath();
			cc.fillStyle = o.o? '#00FFFF':(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			cc.moveTo(o.x - w05 + 1.5, o.y + h05 - 1);
			cc.lineTo(o.x - w05 + h05 + 1, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 1.5, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - h05 - 1, o.y + h05 - 1);
			cc.lineTo(o.x - w05 + 1.5, o.y + h05 - 1);
			cc.closePath();
			cc.fillStyle = o.s?'#00AAEE':(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], x = o.x, y = o.y
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: x, y: y - h05 });
			r.push({ x: x, y: y + h05 });
			r.push({ x: x - w05 + h05 * 0.5, y: y });
			r.push({ x: x + w05 - h05 * 0.5, y: y });
			return r;
		}
		return o;
	}
}
Flow.ProcessNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('process');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 100, h: 40, caption: '' }
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			if(!d.faceId){
				return 'noFaceId';
			};
			if(!d.impl){
				return 'noImpl';
			}
			return '';
			//return o.n.id && o.p && d.code && d.name && d.faceId && d.impl;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, pm: o.pm, p: [], n: -1, c: o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 100);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, x = o.x - m.w * 0.5, y = o.y - m.h * 0.5, ds = o.c.status;
			cc.fillStyle = o.o? '#00FFFF':(ds?'#666666':'#000000');
			cc.fillRect(x, y, m.w, m.h);
			cc.fillStyle = (o.s? '#00AAEE':(ds?'#CCCCCC':'#FFFFFF'));
			cc.fillRect(x + 1, y + 1, m.w - 2, m.h - 2);
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w05 = m.w * 0.5, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.SubflowNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('subflow');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 120, h: 40, caption: '' };
		o.p = {};
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			return '';
			//return o.n.id && o.p && d.code && d.name && d.faceId && d.impl;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1 ,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h + m.h, 120);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, h05 = m.h * 0.5, x = o.x - m.w * 0.5
				, y = o.y - m.h * 0.5, ds = o.c.status;
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');// 边框色 （组件(禁用·未尽用)||普通节点(禁用·未尽用)）
			cc.fillRect(x, y, m.w, m.h);
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');// 填充色 （选中(禁用·未尽用)||普通节点(禁用·未尽用)）
			cc.fillRect(x + 1, y + 1, m.w - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(x + h05, y);
			cc.lineTo(x + h05, y + m.h);
			cc.moveTo(x + m.w - h05, y);
			cc.lineTo(x + m.w - h05, y + m.h);
			cc.closePath();
			cc.strokeStyle = o.o? (ds?'#00008C':'#00FFFF') : (ds?'#666666':'#000000');//
			cc.stroke();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w05 = m.w * 0.5, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.JudgeNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('judge');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 120, h: 48, caption: '' };
		o.p = {};
		o.n = {}; //只能有两个后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = {}; //只能有两个后继
		return this.live(o);
	},
	live: function(o){
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: [], c: o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.check = function(){
			var o = this, d = o.d, nn = o.n, y, n, i = 0;
			for (var k in nn) {
				var t = nn[k].d.tagCode;
				y = y || (t == 'yes');
				n = n || (t == 'no');
				i++;
			}
			if(i!=2){
				return 'aNumWrong';
			};
			if(!y){
				return 'noY';
			};
			if(!n){
				return 'noN';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			if(!d.faceId){
				return 'noFaceId';
			};
			if(!d.impl){
				return 'noImpl';
			}
			return '';
			//return i==2 && y && n && d.code && d.name && d.faceId && d.impl;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h + m.h, 120);
			m.h = Math.max(w * 0.4, 48);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5, ds = o.c.status;
			cc.beginPath();
			cc.moveTo(o.x - w05, o.y);
			cc.lineTo(o.x, o.y - h05);
			cc.lineTo(o.x + w05, o.y);
			cc.lineTo(o.x, o.y + h05);
			cc.lineTo(o.x - w05, o.y);
			cc.closePath();
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			cc.moveTo(o.x - w05 + 3, o.y);
			cc.lineTo(o.x, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 3, o.y);
			cc.lineTo(o.x, o.y + h05 - 1);
			cc.lineTo(o.x - w05 + 3, o.y);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.OutputNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('output');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 120, h: 40, caption: '' };
		o.p = {};
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var d = o.d;
			return o.n.id && o.p && d.code && d.name && d.faceId && d.impl && d.uiCode;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h * 1.5, 120);
			//m.h = Math.max(w * 0.3, 48);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, P05 = Math.PI * 0.5, ds = o.c.status;
			cc.beginPath();
			cc.arc(o.x - w05 + h05, o.y, h05, -P05, P05, true);
			cc.lineTo(o.x + w05 - h05, o.y + h05);
			cc.lineTo(o.x + w05, o.y);
			cc.lineTo(o.x + w05 - h05, o.y - h05);
			cc.closePath();
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			cc.arc(o.x - w05 + h05, o.y, h05 - 1, -P05, P05, true);
			cc.lineTo(o.x + w05 - h05 - 0.75, o.y + h05 - 0.75);
			cc.lineTo(o.x + w05 - 1, o.y);
			cc.lineTo(o.x + w05 - h05 - 0.75, o.y - h05 + 0.75);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.TryNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('try');
		o.x = p.x;
		o.y = p.y;
		o.d.code = 'try';
		o.m = { w: 90, h: 40, caption: 'try' };
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return o.n.id && !o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1 ,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 120);
			//m.h = Math.max(w * 0.3, 48);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x + w05 - h05, y = o.y - h05, ds = o.c.status;
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fillRect(o.x - w05, y, m.w - h05, m.h);
			cc.beginPath();
			cc.moveTo(x, o.y - h05);
			cc.lineTo(o.x + w05, o.y);
			cc.lineTo(x, o.y + h05);
			cc.closePath();
			cc.fill();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(o.x - w05 + 1, y + 1, m.w - h05 - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(x - 1, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 2, o.y);
			cc.lineTo(x - 1, o.y + h05 - 1);
			cc.closePath();
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'left';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x - w05 + 12, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.CatchNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('catch');
		o.x = p.x;
		o.y = p.y;
		o.d.code = 'catch';
		o.m = { w: 90, h: 40, caption: 'catch' };
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return !o.n && o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 120);
			//m.h = Math.max(w * 0.3, 48);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x + w05 - h05, y = o.y - h05, ds = o.c.status;
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fillRect(o.x - w05, y, m.w - h05, m.h);
			cc.beginPath();
			cc.moveTo(x, o.y - h05);
			cc.lineTo(o.x + w05, o.y);
			cc.lineTo(x, o.y + h05);
			cc.closePath();
			cc.fill();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(o.x - w05 + 1, y + 1, m.w - h05 - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(x - 1, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 2, o.y);
			cc.lineTo(x - 1, o.y + h05 - 1);
			cc.closePath();
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'left';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x - w05 + 12, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.FinallyNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('finally');
		o.x = p.x;
		o.y = p.y;
		o.d.code = 'finally';
		o.m = { w: 90, h: 40, caption: 'finally' };
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return o.n.id && !o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 120);
			//m.h = Math.max(w * 0.3, 48);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x + w05 - h05, y = o.y - h05, ds = o.c.status;
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fillRect(o.x - w05, y, m.w - h05, m.h);
			cc.beginPath();
			cc.moveTo(x, o.y - h05);
			cc.lineTo(o.x + w05, o.y);
			cc.lineTo(x, o.y + h05);
			cc.closePath();
			cc.fill();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(o.x - w05 + 1, y + 1, m.w - h05 - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(x - 1, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 2, o.y);
			cc.lineTo(x - 1, o.y + h05 - 1);
			cc.closePath();
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'left';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x - w05 + 12, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.YrtNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('yrt');
		o.x = p.x;
		o.y = p.y;
		o.d.code = 'yrt';
		o.m = { w: 90, h: 40, caption: 'yrt' };
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; // N前驱，一后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return !o.n && o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 120);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x + w05 - h05, y = o.y - h05, ds = o.c.status;
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fillRect(o.x - w05, y, m.w - h05, m.h);
			cc.beginPath();
			cc.moveTo(x, o.y - h05);
			cc.lineTo(o.x + w05, o.y);
			cc.lineTo(x, o.y + h05);
			cc.closePath();
			cc.fill();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(o.x - w05 + 1, y + 1, m.w - h05 - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(x - 1, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 2, o.y);
			cc.lineTo(x - 1, o.y + h05 - 1);
			cc.closePath();
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'left';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x - w05 + 12, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.ForkNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('fork');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 48, h: 48, caption: '' }
		o.p = {};
		o.n = {};
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = {};
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			if(!d.faceId){
				return 'noFaceId';
			};
			if(!d.impl){
				return 'noImpl';
			}
			return '';
			//return o.n && o.p && d.code && d.name && d.faceId && d.impl;
		}
		o.tinto = function(){
			var z = this, N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: [],c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w) {
			var m = o.m;
			//m.w = Math.max(w, 48);
			//m.h = m.w;
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, x = o.x - m.w * 0.5, y = o.y - m.h * 0.5
				, z = m.w / 8, ds = o.c.status;
			cc.fillStyle = '#FFFFFF';
			cc.fillRect(x, y, m.w, m.h);
			cc.fillStyle = o.s ? (ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(x + 1, y + 1, m.w - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(o.x, y + z);
			cc.lineTo(o.x, o.y);
			cc.moveTo(x + z, y + m.h - z);
			cc.lineTo(o.x, o.y);
			cc.moveTo(x + m.w - z, y + m.h - z);
			cc.lineTo(o.x, o.y);
			cc.moveTo(x + z, o.y);
			cc.lineTo(x + m.w - z, o.y);
			cc.closePath();
			cc.strokeStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.stroke();
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return Flow.pointToPoint(p.x, p.y, o.x, o.y) < m.w * 0.5;
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.JoinNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('join');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 48, h: 48, caption: '' }
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			if(!d.faceId){
				return 'noFaceId';
			};
			if(!d.impl){
				return 'noImpl';
			}
			return '';
			//return o.n.id && o.p && d.code && d.name && d.faceId && d.impl;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, pm: o.pm, p: [], n: -1,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 100);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, x = o.x - m.w * 0.5, y = o.y - m.h * 0.5
				, z = m.w / 8, ds = o.c.status;
			cc.fillStyle = '#FFFFFF';
			cc.fillRect(x, y, m.w, m.h);
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(x + 1, y + 1, m.w - 2, m.h - 2);
			cc.beginPath();
			cc.moveTo(x + z, y + z);
			cc.lineTo(o.x, o.y);
			cc.moveTo(x + m.w - z, y + z);
			cc.lineTo(o.x, o.y);
			cc.moveTo(x + z, o.y);
			cc.lineTo(x + m.w - z, o.y);
			cc.moveTo(o.x, o.y);
			cc.lineTo(o.x, y + m.h - z);
			cc.closePath();
			cc.strokeStyle = o.o?(ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.stroke();
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w05 = m.w * 0.5, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.StartNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('start');
		o.x = p.x;
		o.y = p.y;
		o.d.code = 'start';
		o.m = { w: 100, h: 40, caption: '开始' }
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.n = -1; //只能有一个后继
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			if(!o.n.id){
				return 'noid';
			}
			if(o.p){
				return o.p
			}
			return false;
			//return o.n.id && !o.p;
		}		
		o.tinto = function(){
			var z = this, N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 100);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, h05 = m.h * 0.5, w05 = m.w * 0.5
				, p = Math.PI * 0.5, ds = o.c.status;
			cc.beginPath();
			cc.arc(o.x - w05 + h05, o.y, h05, -p, p, true);
			cc.arc(o.x + w05 - h05, o.y, h05, p, -p, true);
			cc.closePath();
			cc.fillStyle = o.o?(ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			cc.arc(o.x - w05 + h05, o.y, h05 - 1, -p, p, true);
			cc.arc(o.x + w05 - h05, o.y, h05 - 1, p, -p, true);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
					&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.EndNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('end');
		o.x = p.x;
		o.y = p.y;
		o.d.code = 'end';
		o.m = { w: 100, h: 40, caption: '结束' };
		o.p = {}; // 不能有后继
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this;
			if(o.n){
				return 'moreEnd';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return !o.n && o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w) {
			var m = o.m;
			m.w = Math.max(w + m.h, 100);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, h05 = m.h * 0.5, w05 = m.w * 0.5
				, p = Math.PI * 0.5, ds = o.c.status;
			cc.beginPath();
			cc.arc(o.x - w05 + h05, o.y, h05, -p, p, true);
			cc.arc(o.x + w05 - h05, o.y, h05, p, -p, true);
			cc.closePath();
			cc.fillStyle = o.o?(ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			cc.arc(o.x - w05 + h05, o.y, h05 - 1, -p, p, true);
			cc.arc(o.x + w05 - h05, o.y, h05 - 1, p, -p, true);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
					&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.SwitchNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('switch');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 48, h: 48, caption: 'S' }
		o.p = {};
		o.n = {};
		return this.live(o);
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = {};
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n){
				return 'noNext';
			};
			if(!o.p){
				return 'noP';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			if(!d.faceId){
				return 'noFaceId';
			};
			if(!d.impl){
				return 'noImpl';
			};
			return '';
			//return o.n && o.p && d.code && d.name && d.faceId && d.impl;
		}
		o.tinto = function(){
			var z = this, N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: [], c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w) {
			var m = o.m;
			//m.w = Math.max(w, 48);
			//m.h = m.w;
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, r = m.h * 0.5, P2 = Math.PI * 2, ds = o.c.status;
			cc.beginPath();
			cc.arc(o.x, o.y, r, 0, P2, true);
			cc.closePath();
			cc.fillStyle = o.o?(ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			cc.arc(o.x, o.y, r - 1, 0, P2, true);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y + 2);
		}
		o.erase = function(cc){
			var m = o.m, r = m.w;
			cc.clearRect(o.x - r * 0.5, o.y - r * 0.5, r, r);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return Flow.pointToPoint(p.x, p.y, o.x, o.y) < m.w * 0.5;
		}
		o.getAnchors = function(){
			var m = o.m, r = []
				, w05 = o.m.w * 0.5, h05 = o.m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.BeginTxNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('beginTx');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 40, h: 40, caption: 'B' }
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return o.n.id && o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1 ,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x - w05, y = o.y - h05, ds = o.c.status;
			cc.beginPath();
			cc.moveTo(x, y);
			cc.lineTo(o.x, o.y + h05);
			cc.lineTo(o.x + w05, y);
			cc.lineTo(x, y);
			cc.closePath();
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			x += 1;
			y += 1;
			cc.moveTo(x, y);
			cc.lineTo(o.x, o.y + h05 - 1);
			cc.lineTo(o.x + w05 - 1, y);
			cc.lineTo(x, y);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w025 = m.w * 0.25, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w025, y: o.y });
			r.push({ x: o.x + w025, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.CommitTxNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('commitTx');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 40, h: 40, caption: 'C' }
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return o.n.id && o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1 ,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x - w05, y = o.y + h05, ds = o.c.status;
			cc.beginPath();
			cc.moveTo(x, y);
			cc.lineTo(o.x, o.y - h05);
			cc.lineTo(o.x + w05, y);
			cc.lineTo(x, y);
			cc.closePath();
			cc.fillStyle = o.o?(ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			x += 1;
			y -= 1;
			cc.moveTo(x, y);
			cc.lineTo(o.x, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 1, y);
			cc.lineTo(x, y);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'top';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w025 = m.w * 0.25, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w025, y: o.y });
			r.push({ x: o.x + w025, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.RollbackTxNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('rollbackTx');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 40, h: 40, caption: 'R' }
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			return '';
			//return o.n.id && o.p;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, x: o.x, y: o.y,
				d: o.d, m: o.m, p: [], n: -1 ,c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.draw = function(cc){
			var m = o.m, w05 = m.w * 0.5, h05 = m.h * 0.5
				, x = o.x - w05, y = o.y + h05, ds = o.c.status;
			cc.beginPath();
			cc.moveTo(x, y);
			cc.lineTo(o.x, o.y - h05);
			cc.lineTo(o.x + w05, y);
			cc.lineTo(x, y);
			cc.closePath();
			cc.fillStyle = o.o?(ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fill();
			cc.beginPath();
			x += 1;
			y -= 1;
			cc.moveTo(x, y);
			cc.lineTo(o.x, o.y - h05 + 1);
			cc.lineTo(o.x + w05 - 1, y);
			cc.lineTo(x, y);
			cc.closePath();
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fill();
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'top';
			cc.fillStyle = ds?'#666666':'#000000';
			cc.fillText(m.caption, o.x, o.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w025 = m.w * 0.25, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w025, y: o.y });
			r.push({ x: o.x + w025, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.SuspendNode = {
	new1: function(p){
		var o = Flow.BaseNode.new1('suspend');
		o.x = p.x;
		o.y = p.y;
		o.m = { w: 40, h: 40, caption: '' }
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	new2: function(z, p){
		var o = Flow.BaseNode.new2(z, p);
		o.p = {};
		o.n = -1; //只能有一个后继
		this.live(o);
		return o;
	},
	live: function(o){
		o.check = function(){
			var o = this, d = o.d;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p){
				return 'noP';
			};
			if(!d.code){
				return 'noCode';
			};
			if(!d.name){
				return 'noName';
			};
			if(!d.faceId){
				return 'noFaceId';
			};
			if(!d.impl){
				return 'noImpl';
			}
			return '';
//			/return o.n.id && o.p && d.code && d.name && d.faceId && d.impl;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, pm: o.pm, p: [], n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 100);
			m.caption = c;
		}
		o.draw = function(cc){
			var m = o.m, x = o.x - m.w * 0.5, y = o.y - m.h * 0.5, ds = o.c.status;
			cc.fillStyle = o.o? (ds?'#00008C':'#00FFFF'):(ds?'#666666':'#000000');
			cc.fillRect(x, y, m.w, m.h);
			cc.fillStyle = o.s?(ds?'#3D8E9C':'#00AAEE'):(ds?'#CCCCCC':'#FFFFFF');
			cc.fillRect(x + 1, y + 1, m.w - 2, m.h - 2);
			cc.fillStyle = ds?'#FFFFFF':'#666666';
			cc.fillRect(o.x - m.w * 0.15, o.y - m.h * 0.2, m.w * 0.1, m.h * 0.4);
			cc.fillRect(o.x + m.w * 0.05, o.y - m.h * 0.2, m.w * 0.1, m.h * 0.4);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(o.x - m.w * 0.5, o.y - m.h * 0.5, m.w, m.h);
		}
		o.onClick = function(p){
			o.s = 1;
			return 1;
		}
		o.onMe = function(p){
			var m = o.m;
			return (Math.abs(p.x - o.x) <= m.w * 0.5
				&& Math.abs(p.y - o.y) <= m.h * 0.5);
		}
		o.getAnchors = function(){
			var m = o.m, r = [], w05 = m.w * 0.5, h05 = m.h * 0.5;
			r.push({ x: o.x, y: o.y - h05 });
			r.push({ x: o.x, y: o.y + h05 });
			r.push({ x: o.x - w05, y: o.y });
			r.push({ x: o.x + w05, y: o.y });
			return r;
		}
		return o;
	}
}
Flow.ArrowNode = {
	new1: function(ac, p1) {
		var o = Flow.BaseNode.new1('arrow');
		o.m = {
			x0: ac.x, y0: ac.y,
			x1: p1.x, y1: p1.y,
			pa: [], a0: ac.i
		}
		o.p = -1;
		o.n = -1;
		return this.live(o);
	},
	live: function(o){
		o.check = function(){
			var o = this;
			if(!o.n.id){
				return 'noId';
			};
			if(!o.p.id){
				return 'noP';
			};
			return '';
			//return o.n.id && o.p.id;
		}
		o.tinto = function(){
			var N = Flow.BaseNode;
			var a = {
				id: o.id, t: o.t, o: o.o, x: o.x, y: o.y,
				d: o.d, m: o.m, p: -1, n: -1, c:o.c
			};
			N.tinto(o, 'p', a);
			N.tinto(o, 'n', a);
			return a;
		}
		o.setCaption = function(c, w){
			var m = o.m;
			m.w = Math.max(w + m.h, 120);
			m.caption = c;
		}
		o.toAnchor = function(t, n, i){
			var m = o.m;
			if (n.id) {
				//哪个端头要移到哪个节点的哪个锚点上
				m['a' + t] = i;
				var a = n.getAnchor(i);
				m['x' + t] = a.x;
				m['y' + t] = a.y;
				return 1;
			}
			return 0;
		}
		o.adjust = function(){
			//根据相对位置调整锚点，锚点：0上 1下 2左 3右
			var o = this, m = o.m, a, x, y
				, n0 = o.p, n1 = o.n, D = 16, D2 = D + D
				, dx = n0.x - n1.x, dy = n0.y - n1.y
				, w005 = n0.m.w * 0.5, h005 = n0.m.h * 0.5
				, w105 = n1.m.w * 0.5, h105 = n1.m.h * 0.5;
			m.pa = []; // 修改途经点
			//$('#head').text('dx = ' + dx + ' / dy = ' + dy);
			if (dy > h005+D) {
				if (dx < w005 + D) {
					o.toAnchor(1, n1, 2);
					o.toAnchor(0, n0, 2);
					x = Math.min(m.x0, m.x1) - D2;
					m.pa.push({ x: x, y: m.y0 });
					m.pa.push({ x: x, y: m.y1 });
				} else {
					o.toAnchor(1, n1, 1);
					o.toAnchor(0, n0, 2);
					m.pa.push({ x: m.x1, y: m.y0 });
				}
				return;
			}
			if (dy < -h005-D) {
				if (dx >= w005+w105+D2) {
					o.toAnchor(0, n0, 1);
					o.toAnchor(1, n1, 3);
					m.pa.push({ x: m.x0, y: m.y1 });
				} else if (dx <= -w005-w105-D2) {
					o.toAnchor(0, n0, 3);
					o.toAnchor(1, n1, 0);
					m.pa.push({ x: m.x1, y: m.y0 });
				} else if (dy > -h005-h105-D){
					o.toAnchor(0, n0, 3);
					o.toAnchor(1, n1, 3);
					x = Math.max(m.x0, m.x1) + D2;
					m.pa.push({ x: x, y: m.y0 });
					m.pa.push({ x: x, y: m.y1 });
				} else {
					o.toAnchor(0, n0, 1);
					o.toAnchor(1, n1, 0);
				}
				return;
			}
			if (Math.abs(dx) < w005+w105+D && Math.abs(dy) <= h005+h105+D) {
				o.toAnchor(0, n0, dx>0? 3:2);
				o.toAnchor(1, n1, dy>0? 0:1);
				if (dx > 0) {
					x = Math.max(m.x0, m.x1) + D2;
				} else {
					x = Math.min(m.x0, m.x1) - D2;
				}
				m.pa.push({ x: x, y: m.y0 });
				y = m.y1 + (dy>0?-D2:D2);
				m.pa.push({ x: x, y: y });
				m.pa.push({ x: m.x1, y: y });
				return;
			}
			o.toAnchor(0, n0, dx>0?2:3);
			o.toAnchor(1, n1, dx>0?3:2);
		}
		o.getMiddlePoint = function(ll){
			function cut(x0, y0, x1, y1, d, r){
				return {
					x: x0 + Math.sin(Math.asin((x1 - x0) / d)) * r,
					y: y0 + Math.cos(Math.acos((y1 - y0) / d)) * r
				}
			}
			var m = o.m, z, l = 0, x = m.x0, y = m.y0;
			for (var i=0; i<m.pa.length; i++) {
				z = m.pa[i];
				d = Flow.pointToPoint(x, y, z.x, z.y);
				l += d;
				if (l * 2 > ll) {
					return cut(z.x, z.y, x, y, d, l - ll * 0.5);
				}
				x = z.x;
				y = z.y;
			}
			d = Flow.pointToPoint(x, y, m.x1, m.y1);
			l += d;
			//$('#head').text(d + ' / ' + l + ' / ' + ll);
			if (l * 2 >= ll) {
				return cut(m.x1, m.y1, x, y, d, l - ll * 0.5);
			}
		}
		o.draw = function(cc) {
			var m = o.m, V = 16, P = Math.PI, P2 = P * 0.5
				, pa = m.pa, d = P * 0.85, z = { x: m.x0, y: m.y0 }
				, ll = 0, l, x, y;
			cc.beginPath();
			cc.strokeStyle = o.s?'#FF0000':(o.d.async?'#00FF00':'#000000');
			cc.moveTo(m.x0, m.y0);
			x = m.x0;
			y = m.y0;
			for (var i=0; i<pa.length; i++) {
				z = pa[i];
				cc.lineTo(z.x, z.y);
				ll += Flow.pointToPoint(x, y, z.x, z.y);
				x = z.x;
				y = z.y;
			}
			cc.lineTo(m.x1, m.y1);
			l = Flow.pointToPoint(x, y, m.x1, m.y1)
			ll += l;
			var s1, s2, s = Math.asin((m.x1 - x) / l)
				, c = Math.acos((m.y1 - y) / l)
			if ((s > -P2 && s < 0 && c < P && c > P2)
				|| (s > 0 && s < P2 && c < P2 && c > 0)) {
				s1 = s + d;
				s2 = s - d;
			} else {
				s1 = s - d;
				s2 = s + d;
			}
			cc.lineTo(m.x1 + Math.sin(s1) * V, m.y1 + Math.cos(c + d) * V);
			cc.moveTo(m.x1, m.y1);
			cc.lineTo(m.x1 + Math.sin(s2) * V, m.y1 + Math.cos(c - d) * V);
			cc.closePath();
			cc.stroke();
			z = o.getMiddlePoint(ll);//找到中间点
			cc.font = '20px sans-serif';
			cc.textAlign = 'center';
			cc.textBaseline = 'middle';
			cc.fillStyle = '#333333';
			cc.fillText(o.d.tagCode || '', z.x, z.y);
		}
		o.erase = function(cc){
			var m = o.m;
			cc.clearRect(Math.min(m.x0, m.x1), Math.min(m.y0, m.y1)
				, Math.abs(m.x1 - m.x0), Math.abs(m.y1 - m.y0));
		}
		o.onClick = function(p){
			o.s = 1;
			return o.s;
		}
		o.onMe = function(p){
			var m = o.m, x = o.x, y = o.y;
			if (m.pa.length) {
				var a = [{ x: m.x0, y: m.y0 }]
					.concat(m.pa).concat([{ x: m.x1, y: m.y1 }]);
				for (var i=0; i<a.length; i++) {
					var z = a[i];
					o.s = Flow.pointToLineD(p.x, p.y, x, y, z.x, z.y) < 8? 1:0;
					if (o.s) {
						return o.s;
					}
					x = z.x;
					y = z.y;
				}
			} else {
				o.s = Flow.pointToLineD(p.x, p.y, m.x0, m.y0, m.x1, m.y1) < 8? 1:0;
			}
			return o.s;
		}
		return o;
	}
}
Flow.Nodes = {
	'start': Flow.StartNode,
	'end': Flow.EndNode,
	'input': Flow.InputNode,
	'output': Flow.OutputNode,
	'process': Flow.ProcessNode,
	'subflow': Flow.SubflowNode,
	'arrow': Flow.ArrowNode,
	'judge': Flow.JudgeNode,
	'switch': Flow.SwitchNode,
	'try': Flow.TryNode,
	'catch': Flow.CatchNode,
	'finally': Flow.FinallyNode,
	'yrt': Flow.YrtNode,
	'beginTx': Flow.BeginTxNode,
	'commitTx': Flow.CommitTxNode,
	'rollbackTx': Flow.RollbackTxNode,
	'fork': Flow.ForkNode,
	'join': Flow.JoinNode,
	'suspend': Flow.SuspendNode
}